home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / dev / lang / sofa.lha / sofa / smalleiffel / lib_number / large_negative_integer.e < prev    next >
Text File  |  2000-03-25  |  10KB  |  401 lines

  1. -- This file is  free  software, which  comes  along  with  SmallEiffel. This
  2. -- software  is  distributed  in the hope that it will be useful, but WITHOUT 
  3. -- ANY  WARRANTY;  without  even  the  implied warranty of MERCHANTABILITY or
  4. -- FITNESS  FOR A PARTICULAR PURPOSE. You can modify it as you want, provided
  5. -- this header is kept unaltered, and a notification of the changes is added.
  6. -- You  are  allowed  to  redistribute  it and sell it, alone or as a part of 
  7. -- another product.
  8. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  9. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  10. --                       http://SmallEiffel.loria.fr
  11. --
  12. class LARGE_NEGATIVE_INTEGER
  13. --
  14. -- To implement NUMBER (do not use this class, see NUMBER).
  15. --
  16.        
  17. inherit LARGE_INTEGER;
  18.    
  19. creation make_from_fixed_array, make_smaller, make_from_product, make_big
  20.  
  21. feature
  22.  
  23.    is_positive: BOOLEAN is false;
  24.    
  25.    is_negative: BOOLEAN is true;
  26.        
  27.    to_integer: INTEGER is
  28.       do
  29.      Result := Minimum_integer;
  30.       end;
  31.    
  32.    to_double: DOUBLE is
  33.       do
  34.      Result := - fixed_array_to_double(value);
  35.       end;
  36.    
  37.    prefix "-": NUMBER is
  38.       do
  39.      !LARGE_POSITIVE_INTEGER!Result.make_from_fixed_array(value);
  40.       end;
  41.  
  42.      
  43.    infix "+" (other: NUMBER): NUMBER is
  44.       do
  45.      Result := other.add_with_large_negative_integer(Current);
  46.       end;
  47.  
  48.    infix "@+" (other: INTEGER): NUMBER is
  49.       do     
  50.      if (other = 0 ) then
  51.         Result := clone( Current )
  52.      elseif (other > 0) then
  53.         temp_1_digint.put(other, 0);
  54.         difference_between_fixed_arrays(value, temp_1_digint);
  55.         Result := create_negative(temp);
  56.      else
  57.         if (other /= Minimum_integer) then
  58.            temp_1_digint.put(other.abs, 0);
  59.            add_fixed_arrays(value, temp_1_digint);
  60.    
  61.         else
  62.            temp_2_digints.put(0,0);
  63.            temp_2_digints.put(1,1);
  64.            add_fixed_arrays(value, temp_2_digints);
  65.         end;
  66.         !LARGE_NEGATIVE_INTEGER!Result.make_from_fixed_array(clone(temp));
  67.      end;
  68.       end; 
  69.  
  70.    infix "*" (other: NUMBER): NUMBER is
  71.       do
  72.      Result := other.multiply_with_large_negative_integer(Current);
  73.       end;
  74.       
  75.    infix "@*"(other : INTEGER): NUMBER is
  76.       do
  77.      if (other = 0) then
  78.         Result := zero;
  79.      elseif (other > 0) then 
  80.         mult_fixed_with_integer(value, other);
  81.         !LARGE_NEGATIVE_INTEGER!Result.make_from_fixed_array(clone(temp));
  82.      else
  83.         if (other = Minimum_integer) then
  84.            mult_2_fixed(value, smaller_correct_fixed);
  85.            !LARGE_POSITIVE_INTEGER!Result.make_from_fixed_array(clone(temp_from_mult));
  86.         else
  87.            mult_fixed_with_integer(value, other.abs);
  88.            !LARGE_POSITIVE_INTEGER!Result.make_from_fixed_array(clone(temp));
  89.         end;
  90.      end;
  91.       end;
  92.    
  93.    infix "@/" (other: INTEGER): NUMBER is
  94.       require
  95.      other /= 0;
  96.       local      
  97.      d: ABSTRACT_INTEGER;
  98.       do
  99.      if (other = 1) then
  100.         Result := Current;
  101.      elseif (other = -1) then
  102.         Result := -Current;
  103.      else
  104.         !SMALL_INTEGER!d.make(other);
  105.         Result := Current / d;
  106.      end;
  107.       end;
  108.    
  109.    infix "//" (other: NUMBER): NUMBER is
  110.       local
  111.      oth: ABSTRACT_INTEGER;
  112.       do
  113.      oth ?= other;
  114.      Result := oth.integer_divide_large_negative_integer(Current);
  115.       end;
  116.    
  117.    infix "@//" (other: INTEGER): NUMBER is
  118.       do
  119.      if (other = Minimum_integer) then
  120.         divise_fixed_array(value, smaller_correct_fixed);
  121.         Result := create_positive(temp_quotient);
  122.      else    
  123.         temp_1_digint.put(other.abs,0);
  124.         divise_fixed_array(value, temp_1_digint);
  125.         if (other < 0) then
  126.            Result := create_positive(temp_quotient);
  127.         else
  128.            Result := create_negative(temp_quotient);
  129.         end;
  130.      end;
  131.       end;
  132.    
  133.    infix "\\" (other: NUMBER): NUMBER is
  134.       local
  135.      oth: ABSTRACT_INTEGER;
  136.       do
  137.      oth ?= other;
  138.      Result := oth.remainder_of_divide_large_negative_integer(Current);
  139.       end;
  140.    
  141. feature {NUMBER}
  142.    
  143.    add_with_large_positive_integer(other: LARGE_POSITIVE_INTEGER): NUMBER is
  144.       do
  145.      Result := other.add_with_large_negative_integer(Current);
  146.       end;
  147.    
  148.    add_with_large_negative_integer(other: LARGE_NEGATIVE_INTEGER): NUMBER is
  149.       do
  150.      add_fixed_arrays(value, other.value);
  151.      !LARGE_NEGATIVE_INTEGER!Result.make_from_fixed_array(clone(temp));
  152.       end;
  153.    
  154.    add_with_small_fraction(other: SMALL_FRACTION): NUMBER is
  155.       do
  156.      Result := other.add_with_large_negative_integer( Current );
  157.       end;
  158.    
  159.    add_with_large_fraction(other: LARGE_FRACTION): NUMBER is
  160.       do
  161.      Result := other.add_with_large_negative_integer( Current );
  162.       end;
  163.          
  164.    multiply_with_large_positive_integer(other: LARGE_POSITIVE_INTEGER): NUMBER is
  165.       do
  166.     Result := other.multiply_with_large_negative_integer( Current ); 
  167.       end;
  168.    
  169.    multiply_with_large_negative_integer(other: LARGE_NEGATIVE_INTEGER): NUMBER is
  170.       do 
  171.      mult_2_fixed(value, other.value);
  172.      !LARGE_POSITIVE_INTEGER!Result.make_from_fixed_array(clone(temp_from_mult));
  173.       end;
  174.    
  175.    multiply_with_small_fraction (other: SMALL_FRACTION): NUMBER is
  176.       do
  177.      Result := other.multiply_with_large_negative_integer(Current);
  178.       end;
  179.    
  180.    multiply_with_large_fraction (other: LARGE_FRACTION): NUMBER is
  181.       do
  182.      Result := other.multiply_with_large_negative_integer(Current);
  183.       end;
  184.    
  185.    integer_divide_small_integer(other: SMALL_INTEGER): ABSTRACT_INTEGER is
  186.       do
  187.      if (other @= Minimum_integer) then
  188.         divise_fixed_array(smaller_correct_fixed, value);
  189.         Result := create_positive(temp_quotient);
  190.      else    
  191.         temp_1_digint.put(other.to_integer.abs,0); 
  192.         divise_fixed_array(temp_1_digint, value);
  193.         if (other @< 0) then
  194.            Result := create_positive(temp_quotient);
  195.         else
  196.            Result := create_negative(temp_quotient);
  197.         end;
  198.      end;
  199.       end; 
  200.       
  201.    integer_divide_large_positive_integer(other: LARGE_POSITIVE_INTEGER): ABSTRACT_INTEGER is
  202.       do
  203.      divise_fixed_array(other.value, value);
  204.      Result := create_negative(temp_quotient);
  205.       end;
  206.    
  207.    integer_divide_large_negative_integer(other: LARGE_NEGATIVE_INTEGER): ABSTRACT_INTEGER is
  208.       do 
  209.      divise_fixed_array(other.value, value);
  210.      Result := create_positive(temp_quotient);
  211.       end;
  212.    
  213.    remainder_of_divide_small_integer(other: SMALL_INTEGER): ABSTRACT_INTEGER is
  214.       do
  215.      if (other @= Minimum_integer) then
  216.         divise_fixed_array(smaller_correct_fixed, value);
  217.         Result := create_negative(temp_remainder);
  218.      else    
  219.         temp_1_digint.put(other.to_integer.abs,0);
  220.         divise_fixed_array(temp_1_digint, value);
  221.         if (other @< 0) then
  222.            Result := create_negative(temp_remainder);
  223.         else
  224.            Result := create_positive(temp_remainder);
  225.         end;
  226.      end;
  227.       end; 
  228.       
  229.    remainder_of_divide_large_positive_integer(other: LARGE_POSITIVE_INTEGER): ABSTRACT_INTEGER is
  230.       do
  231.      divise_fixed_array(other.value, value);
  232.      Result := create_positive(temp_remainder);
  233.       end;
  234.    
  235.    remainder_of_divide_large_negative_integer(other: LARGE_NEGATIVE_INTEGER): ABSTRACT_INTEGER is
  236.       do
  237.      divise_fixed_array(other.value, value);
  238.      Result := create_negative(temp_remainder);
  239.       end;
  240.  
  241.    infix "@\\" (other: INTEGER): NUMBER is
  242.       do
  243.      if (other = Minimum_integer) then
  244.         divise_fixed_array(value, smaller_correct_fixed);
  245.         Result := create_negative(temp_remainder);
  246.      else    
  247.         temp_1_digint.put(other.abs,0);
  248.         divise_fixed_array(value, temp_1_digint);
  249.         if (other < 0) then
  250.            Result := create_negative(temp_remainder);
  251.         else
  252.            Result := create_positive(temp_remainder);
  253.         end;
  254.      end;
  255.       end;
  256.       
  257.    
  258. feature {NUMBER} -- inverse   
  259.    
  260.    inverse: NUMBER is
  261.       local
  262.      num: SMALL_INTEGER;
  263.      den: LARGE_POSITIVE_INTEGER;
  264.       do
  265.      den ?= abs;
  266.      num ?= one;
  267.      !LARGE_FRACTION!Result.make_simply(num, den, true);
  268.       end;
  269.    
  270.    
  271. feature -- Comparisons with INTEGER
  272.    
  273.    infix "@=" (other: INTEGER): BOOLEAN is
  274.       do
  275.          if (other = Minimum_integer) then
  276.         Result := ((value.upper = 1) 
  277.                and then (value.item(1) = 1) 
  278.                and then (value.item(0) = 0));
  279.      else
  280.      end;
  281.       end;
  282.    
  283.    infix "@<" (other: INTEGER): BOOLEAN is
  284.       do
  285.          Result := (other /= Minimum_integer) or else not( same_as(greater_large_negative_integer) );
  286.       end;
  287.    
  288.    infix "@>" (other: INTEGER): BOOLEAN is
  289.       do
  290.       end; 
  291.    
  292.    infix "@<=" (other: INTEGER): BOOLEAN is
  293.       do
  294.      Result := true
  295.       end; 
  296.    
  297.    infix "@>=" (other: INTEGER): BOOLEAN is
  298.       do
  299.      Result := Current @= other
  300.       end; 
  301.    
  302. feature -- Comparisons with NUMBER
  303.    
  304.       infix "<" (other: NUMBER): BOOLEAN is
  305.       do
  306.      Result := other.greater_with_large_negative_integer(Current);
  307.       end
  308.    
  309. feature -- Comparisons with DOUBLE
  310.    
  311.    infix "#=" (other: DOUBLE): BOOLEAN is
  312.       do
  313.      if other > Minimum_integer then
  314.      else
  315.         Result := to_double = other;
  316.      end;
  317.       end;
  318.    
  319.    infix "#<" (other: DOUBLE): BOOLEAN is
  320.       do
  321.      if other > Minimum_integer then
  322.         Result := true 
  323.      else
  324.         Result := to_double < other;
  325.      end;
  326.      end;
  327.    
  328.    infix "#<=" (other: DOUBLE): BOOLEAN is
  329.       do
  330.      if other > Minimum_integer then
  331.         Result := true
  332.      else
  333.         Result := to_double <= other;
  334.      end;
  335.       end;
  336.    
  337.    infix "#>" (other: DOUBLE): BOOLEAN is
  338.       do
  339.      if other > Minimum_integer then
  340.      else
  341.         Result := to_double > other;
  342.      end;
  343.       end;
  344.    
  345.    infix "#>=" (other: DOUBLE): BOOLEAN is
  346.       do
  347.      if other > Minimum_integer then
  348.      else
  349.         Result := to_double >= other;
  350.      end;
  351.       end;
  352.    
  353. feature{NUMBER}
  354.    
  355.    greater_with_large_positive_integer(other: LARGE_POSITIVE_INTEGER): BOOLEAN is 
  356.       do
  357.       end;
  358.    
  359.    greater_with_large_negative_integer(other: LARGE_NEGATIVE_INTEGER): BOOLEAN is 
  360.       local
  361.      i: INTEGER;
  362.       do 
  363.      if (value.upper = other.value.upper) then
  364.         from
  365.            i := value.upper;        
  366.         variant
  367.            i
  368.         until
  369.             (i < value.lower) or else (value.item(i) /= other.value.item(i))
  370.         loop
  371.            i := i - 1;
  372.         end;        
  373.         Result := (i /= value.lower - 1) 
  374.            and then (value.item(i) < other.value.item(i));
  375.      else        
  376.         Result := (value.upper < other.value.upper);  
  377.      end;
  378.       end;
  379.  
  380.    greater_with_small_fraction(other: SMALL_FRACTION): BOOLEAN is 
  381.       do
  382.       end;
  383.    
  384.    greater_with_large_fraction(other: LARGE_FRACTION): BOOLEAN is 
  385.       do
  386.         Result := not(other.greater_with_large_negative_integer(Current));
  387.       end;
  388.    
  389.  
  390. end -- LARGE_NEGATIVE_INTEGER
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.